home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 2: CDPD 1 / Almathera Ten on Ten - Disc 2: CDPD 1.iso / pd / 076-100 / 085 / csh / comm1.c next >
C/C++ Source or Header  |  1995-03-13  |  15KB  |  759 lines

  1. /*
  2.  * COMM1.C
  3.  *
  4.  * Matthew Dillon, August 1986
  5.  *
  6.  * version 2.06M (Manx Version and Additions) by Steve Drew 28-May-87
  7.  *
  8.  */
  9.  
  10. #include "shell.h"
  11. typedef struct FileInfoBlock FIB;
  12.  
  13. #define DIR_SHORT 0x01
  14. #define DIR_FILES 0x02
  15. #define DIR_DIRS  0x04
  16.  
  17. extern int has_wild;
  18. char cwd[256];
  19.  
  20. /*
  21.     Parse the options specified in sw[]
  22.     Setting a bit for each one found
  23. */
  24. get_opt(sw,count)
  25. char *sw;
  26. int *count;
  27. {
  28.    int l,i = 0, opt = 0;
  29.    char *c,*s;
  30.  
  31.    while((++i < ac) && (av[i][0] == '-')) {
  32.     for (c = av[i]+1; *c ; c++) {
  33.         for(l = 0,s = sw;*s && *s != *c; ++s) ++l;
  34.         if (*s) opt |= (1 << l);
  35.     }
  36.    }
  37.    *count = i;
  38.    return(opt);
  39. }
  40.  
  41. do_sleep()
  42. {
  43.    register int i;
  44.  
  45.    if (ac == 2) {
  46.       i = atoi(av[1]);
  47.       while (i > 0) {
  48.      Delay ((long)100);
  49.      i -= 2;
  50.      if (CHECKBREAK())
  51.         break;
  52.       }
  53.    }
  54.    return (0);
  55. }
  56.  
  57.  
  58. do_number()
  59. {
  60.    return (0);
  61. }
  62.  
  63. do_cat()
  64. {
  65.    FILE *fopen(), *fi;
  66.    int i;
  67.    char buf[256];
  68.  
  69.    if (ac == 1) {
  70.       while (gets(buf)) {
  71.      if (CHECKBREAK()) break;
  72.      puts(buf);
  73.      }
  74.       clearerr(stdin);
  75.       return (0);
  76.    }
  77.  
  78.    for (i = 1; i < ac; ++i) {
  79.       if ((fi = fopen (av[i], "r")) != 0) {
  80.        while (fgets(buf,256,fi)) {
  81.         fputs(buf,stdout);
  82.         fflush(stdout);
  83.         if (CHECKBREAK()) {
  84.            breakreset();
  85.            break;
  86.         }
  87.      }
  88.      fclose (fi);
  89.       } else {
  90.      ierror(av[i], 205);
  91.       }
  92.    }
  93.    return (0);
  94. }
  95.  
  96. do_devinfo()
  97. {
  98.    struct DPTR        *dp;
  99.    struct InfoData    *info;
  100.    int stat,i;
  101.    char *p,*s,*get_pwd(),*index();
  102.  
  103.    if (ac == 1) {
  104.       ++ac;
  105.       av[1] = "";
  106.    }
  107.    for (i=1; i < ac; ++i) {
  108.       if (!(dp = dopen (av[i], &stat)))
  109.      continue;
  110.       info = (struct InfoData *)AllocMem((long)sizeof(struct InfoData), MEMF_PUBLIC);
  111.       if (Info (dp->lock, info)) {
  112.  
  113.      s = get_pwd(dp->lock);
  114.      p = index(s,':');
  115.      *p = '\0';
  116.  
  117.      printf ("Unit:%2ld  Errs:%3ld    Used: %-4ld %3ld%% Free: %-4ld    Volume: %s\n",
  118.          info->id_UnitNumber,
  119.          info->id_NumSoftErrors,
  120.          info->id_NumBlocksUsed,
  121.          (info->id_NumBlocksUsed * 100)/ info->id_NumBlocks,
  122.          (info->id_NumBlocks - info->id_NumBlocksUsed),
  123.          s);
  124.  
  125.       } else {
  126.          pError (av[i]);
  127.       }
  128.       FreeMem (info,(long) sizeof(*info));
  129.       dclose(dp);
  130.    }
  131.    return(0);
  132. }
  133.  
  134.  
  135.  
  136. /* things shared with display_file */
  137.  
  138. char  lspec[128];
  139. int   filecount, col;
  140. long  bytes, blocks;
  141.  
  142. /*
  143.  * the args passed to do_dir will never be expanded
  144.  */
  145. do_dir()
  146. {
  147.    void display_file();
  148.    int i, options;
  149.  
  150.    col = filecount = 0;
  151.    bytes = blocks = 0L;
  152.    *lspec = '\0';
  153.  
  154.    options  = get_opt("sfd",&i);
  155.  
  156.    if (ac == i) {
  157.       ++ac;
  158.       av[i] = "";
  159.    }
  160.    if (!(options & (DIR_FILES | DIR_DIRS)))  options |= (DIR_FILES | DIR_DIRS);
  161.  
  162.    for (; i < ac; ++i) {
  163.       char **eav;
  164.       int c,eac;
  165.       if (!(eav = expand(av[i], &eac)))
  166.      continue;
  167.       QuickSort(eav, eac);
  168.       for(c=0;c < eac && !breakcheck();++c) display_file(options,eav[c]);
  169.       free_expand (eav);
  170.       if (CHECKBREAK()) break;
  171.    }
  172.    if (col)  printf("\n");
  173.    if (filecount > 1) {
  174.       blocks += filecount;     /* account for dir blocks */
  175.       printf (" %ld Blocks, %ld Bytes used in %d files\n", blocks, bytes, filecount);
  176.    }
  177.    return (0);
  178. }
  179.  
  180. void
  181. display_file(options,filestr)
  182. int options;
  183. char *filestr;
  184. {
  185.    long atol();
  186.    int isadir,slen;
  187.    char sc;
  188.    char *c,*s,*fi;
  189.    struct FileLock *lock;
  190.    char *get_pwd();
  191.    char *strcpy();
  192.    
  193. /*     if current dir different from lspec then
  194.        look for ':' or '/' if found lock it and get_pwd.
  195.        else then use cwd.
  196. */
  197.    for(s = c = filestr; *c; ++c) if (*c == ':' || *c == '/') s = c;
  198.    if (*s == ':') ++s;
  199.    sc = *s;
  200.    *s = '\0';
  201.    c = filestr;
  202.    if (!*c) c = cwd;
  203.    if (strcmp (c, &lspec))  {
  204.       strcpy(lspec, c);
  205.       if (col)      printf("\n");
  206.       if (lock = (struct FileLock *)Lock(c,SHARED_LOCK)) {
  207.      printf ("Directory of %s\n", get_pwd(lock));
  208.      UnLock(lock);
  209.       }
  210.       col = 0;
  211.    }
  212.    *s = sc;
  213.    if (sc == '/') s++;
  214.    slen = strlen(s);
  215.    fi = s + slen + 1;
  216.    isadir = (fi[9] =='D');
  217.  
  218.    if (!(((options & DIR_FILES) && isadir) ||
  219.      ((options & DIR_DIRS)    && !isadir)))
  220.       return;
  221.  
  222.    if (options & DIR_SHORT) {
  223.       if ((col == 3) && slen >18) {
  224.      printf("\n");
  225.      col = 0;
  226.       }
  227.       if (isadir)  {
  228.      printf ("\033[3m");
  229.       }
  230.       if (slen >18) {
  231.      printf(" %-37s",s);
  232.      col += 2;
  233.       }
  234.       else {
  235.      printf(" %-18s",s);
  236.      col++;
  237.       }
  238.       if (col > 3) {
  239.      printf("\n");
  240.      col = 0;
  241.       }
  242.       if (isadir) printf("\033[0m");
  243.    }
  244.    else        /* print full info */
  245.       printf("   %-24s %s",s ,fi);
  246.    fflush(stdout);
  247.    fi[12] = fi[17] = '\0';
  248.    bytes  += atol(fi+6);
  249.    blocks += atol(fi+13);
  250.    filecount++;
  251.    return;
  252. }
  253.  
  254. /*
  255.    converts dos date stamp to a time string of form dd-mmm-yy
  256. */
  257. char *
  258. dates(dss)
  259. struct DateStamp *dss;
  260. {
  261.    register struct tm tm;
  262.    register long time, t;
  263.    register int i;
  264.    static char timestr[20];
  265.    static char months[12][4] = {
  266.     "Jan","Feb","Mar","Apr","May","Jun",
  267.     "Jul","Aug","Sep","Oct","Nov","Dec"
  268.    };
  269.    static char days[12] = {
  270.     31,28,31,30,31,30,31,31,30,31,30,31
  271.    };
  272.    time = dss->ds_Days * 24 * 60 * 60 + dss->ds_Minute * 60 +
  273.                        dss->ds_Tick/TICKS_PER_SECOND;
  274.    tm.tm_sec = time % 60; time /= 60;
  275.    tm.tm_min = time % 60; time /= 60;
  276.    tm.tm_hour= time % 24; time /= 24;
  277.    tm.tm_wday= time %  7;
  278.    tm.tm_year= 78 + (time/(4*365+1)) * 4; time %= 4 * 365 + 1;
  279.    while (time) {
  280.     t = 365;
  281.     if ((tm.tm_year&3) == 0) t++;
  282.     if (time < t) break;
  283.     time -= t;
  284.     tm.tm_year++;
  285.    }
  286.    tm.tm_yday = ++time;
  287.    for (i=0;i<12;i++) {
  288.     t = days[i];
  289.     if (i == 1 && (tm.tm_year&3) == 0) t++;
  290.     if (time <= t) break;
  291.     time -= t;
  292.    }
  293.    tm.tm_mon = i;
  294.    tm.tm_mday = time;
  295.  
  296.    sprintf(timestr,"%02d-%s-%2d %02d:%02d:%02d\n",tm.tm_mday,
  297.         months[tm.tm_mon],tm.tm_year,
  298.         tm.tm_hour,tm.tm_min,tm.tm_sec);
  299.    return(timestr);
  300.  
  301. }
  302.  
  303. date()
  304. {
  305.    struct   DateStamp    dss;
  306.    char *dates();
  307.  
  308.    DateStamp(&dss);
  309.    printf("%s",dates(&dss));
  310.    return(0);
  311. }
  312.  
  313. do_quit()
  314. {
  315.    if (Src_stack) {
  316.       Quit = 1;
  317.       return(do_return());
  318.    }
  319.    main_exit (0);
  320. }
  321.  
  322.  
  323. do_echo(str)
  324. char *str;
  325. {
  326.    register char *ptr;
  327.    char nl = 1;
  328.  
  329.    for (ptr = str; *ptr && *ptr != ' '; ++ptr);
  330.    if (*ptr == ' ')
  331.       ++ptr;
  332.    if (av[1] && strcmp (av[1], "-n") == 0) {
  333.       nl = 0;
  334.       ptr += 2;
  335.       if (*ptr == ' ')
  336.      ++ptr;
  337.    }
  338.    printf("%s",ptr);
  339.    fflush(stdout);
  340.    if (nl)
  341.       printf("\n");
  342.    return (0);
  343. }
  344.  
  345. do_source(str)
  346. char *str;
  347. {
  348.    register FILE *fi;
  349.    char buf[256];
  350.  
  351.    if (Src_stack == MAXSRC) {
  352.       fprintf (stderr,"Too many source levels\n");
  353.       return(-1);
  354.    }
  355.    if ((fi = fopen (av[1], "r")) == 0) {
  356.       ierror(av[1], 205);
  357.       return(-1);
  358.    }
  359.    set_var(LEVEL_SET, V_PASSED, next_word(next_word(str)));
  360.    ++H_stack;
  361.    Src_pos[Src_stack] = 0;
  362.    Src_base[Src_stack] = (long)fi;
  363.    ++Src_stack;
  364.    while (fgets (buf, 256, fi)) {
  365.       buf[strlen(buf)-1] = '\0';
  366.       Src_pos[Src_stack - 1] += 1+strlen(buf);
  367.       if (Verbose)
  368.      fprintf(stderr,"%s\n",buf);
  369.       exec_command (buf);
  370.       if (CHECKBREAK())
  371.      break;
  372.    }
  373.    --H_stack;
  374.    --Src_stack;
  375.    unset_level(LEVEL_LABEL + Src_stack);
  376.    unset_var(LEVEL_SET, V_PASSED);
  377.    fclose (fi);
  378.    return (0);
  379. }
  380.  
  381.  
  382. /*
  383.  * return ptr to string that contains full cwd spec.
  384.  */
  385. char *
  386. get_pwd(flock)
  387. struct FileLock *flock;
  388. {
  389.    char *ptr;
  390.    char *name;
  391.    int err=0;
  392.    static char pwdstr[256];
  393.  
  394.    struct FileLock *lock, *newlock;
  395.    FIB *fib;
  396.    int i, len;
  397.  
  398.    lock = (struct FileLock *)DupLock(flock);
  399.          
  400.    fib = (FIB *)AllocMem((long)sizeof(FIB), MEMF_PUBLIC);
  401.    pwdstr[i = 255] = '\0';
  402.  
  403.    while (lock) {
  404.       newlock = (struct FileLock *)ParentDir(lock);
  405.       if (!Examine(lock, fib)) ++err;
  406.       name = fib->fib_FileName;
  407.       if (*name == '\0')        /* HACK TO FIX RAM: DISK BUG */
  408.      name = "RAM";
  409.       len = strlen(name);
  410.       if (newlock) {
  411.      if (i == 255) {
  412.         i -= len;
  413.         bmov(name, pwdstr + i, len);
  414.      } else {
  415.         i -= len + 1;
  416.         bmov(name, pwdstr + i, len);
  417.         pwdstr[i+len] = '/';
  418.      }
  419.       } else {
  420.      i -= len + 1;
  421.      bmov(name, pwdstr + i, len);
  422.      pwdstr[i+len] = ':';
  423.       }
  424.       UnLock(lock);
  425.       lock = newlock;
  426.    }
  427.    FreeMem(fib, (long)sizeof(FIB));
  428.    movmem(pwdstr + i, pwdstr, 256 - i);
  429.    if (err) return(cwd);
  430.    return(pwdstr);
  431. }
  432.  
  433. /*
  434.  * set process cwd name and $_cwd, if str != NULL also print it.
  435.  */
  436. do_pwd(str)
  437. char *str;
  438. {
  439.    char *ptr;
  440.  
  441.    if ((struct FileLock *)Myprocess->pr_CurrentDir == 0)
  442.        attempt_cd(":"); /* if we just booted 0 = root lock */
  443.    strcpy(cwd,get_pwd(Myprocess->pr_CurrentDir,1));
  444.    if (str)
  445.       puts(cwd);
  446.    set_var(LEVEL_SET, V_CWD, cwd);
  447.    /* put the current dir name in our CLI task structure */
  448.    ptr = (char *)((ULONG)((struct CommandLineInterface *)
  449.       BADDR(Myprocess->pr_CLI))->cli_SetName << 2);
  450.    ptr[0] = strlen(cwd);
  451.    movmem(cwd,ptr+1,(int)ptr[0]);
  452.    return(0);
  453. }
  454.  
  455.  
  456. /*
  457.  * CD
  458.  *
  459.  * CD(str, 0)        -do CD operation.
  460.  *
  461.  *    standard operation: breakup path by '/'s and process independantly
  462.  *    x:    -reset cwd base
  463.  *    ..    -remove last cwd element
  464.  *    N        -add N or /N to cwd
  465.  */
  466.  
  467. do_cd(str)
  468. char *str;
  469. {
  470.    char sc, *ptr;
  471.    int err=0;
  472.  
  473.    str = next_word(str);
  474.    if (*str == '\0') {
  475.       puts(cwd);
  476.       return(0);
  477.    }
  478.    str[strlen(str)+1] = '\0';           /* add second \0 on end */
  479.    while (*str) {
  480.       for (ptr = str; *ptr && *ptr != '/' && *ptr != ':'; ++ptr);
  481.       switch (*ptr) {
  482.       case ':':
  483.      sc = ptr[1];
  484.      ptr[1] = '\0';
  485.      err = attempt_cd(str);
  486.      ptr[1] = sc;
  487.      break;
  488.       case '\0':
  489.       case '/':
  490.      *ptr = '\0';
  491.      if (strcmp(str, "..") == 0 || str == ptr)
  492.         str = "/";
  493.      if (*str) err = attempt_cd(str);
  494.      break;
  495.       }
  496.       if (err) break;
  497.       str = ptr + 1;
  498.    }
  499.    do_pwd(NULL);     /* set $_cwd */
  500.    return(err);
  501. }
  502.  
  503. attempt_cd(str)
  504. char *str;
  505. {
  506.    struct FileLock *oldlock, *filelock;
  507.  
  508.    if (filelock = (struct FileLock *)Lock(str, ACCESS_READ)) {
  509.       if (isdir(str)) {
  510.      if (oldlock = (struct FileLock *)CurrentDir(filelock))
  511.         UnLock(oldlock);
  512.      return (0);
  513.       }
  514.       UnLock(filelock);
  515.       ierror(str, 212);
  516.    } else {
  517.       ierror(str, 205);
  518.    }
  519.    return (-1);
  520. }
  521.  
  522. do_mkdir()
  523. {
  524.    register int i;
  525.    register struct FileLock *lock;
  526.  
  527.    for (i = 1; i < ac; ++i) {
  528.       if (lock = (struct FileLock *)Lock(av[i],ACCESS_READ)) {
  529.      ierror(av[i],203);
  530.      UnLock (lock);
  531.      continue;
  532.       }
  533.       if (lock = (struct FileLock *)CreateDir (av[i])) {
  534.      UnLock (lock);
  535.      continue;
  536.       }
  537.       pError (av[i]);
  538.    }
  539.    return (0);
  540. }
  541.  
  542.  
  543. do_mv()
  544. {
  545.    char dest[256];
  546.    register int i;
  547.    char *str;
  548.  
  549.    --ac;
  550.    if (isdir(av[ac])) {
  551.       for (i = 1; i < ac; ++i) {
  552.      str = av[i] + strlen(av[i]) - 1;
  553.      while (str != av[i] && *str != '/' && *str != ':')
  554.         --str;
  555.      if (str != av[i])
  556.         ++str;
  557.      if (*str == 0) {
  558.         ierror(av[i], 508);
  559.         return (-1);
  560.      }
  561.      strcpy(dest, av[ac]);
  562.      if (dest[strlen(dest)-1] != ':')
  563.         strcat(dest, "/");
  564.      strcat(dest, str);
  565.      if (Rename(av[i], dest) == 0)
  566.         break;
  567.       }
  568.       if (i == ac)
  569.      return (1);
  570.    } else {
  571.       i = 1;
  572.       if (ac != 2) {
  573.      ierror("", 507);
  574.      return (-1);
  575.       }
  576.       if (Rename (av[1], av[2]))
  577.      return (0);
  578.    }
  579.    pError (av[i]);
  580.    return (-1);
  581. }
  582.  
  583. rm_file(file)
  584. char *file;
  585. {
  586.       if (has_wild) printf("  %s...",file);
  587.       fflush(stdout);
  588.       if (!DeleteFile(file))
  589.      pError (file);
  590.       else
  591.      if (has_wild) printf("Deleted\n");
  592. }
  593.  
  594. do_rm()
  595. {
  596.    int i, recur;
  597.  
  598.    recur = get_opt("r",&i);
  599.  
  600.    for (; i < ac; ++i) {
  601.       if (CHECKBREAK()) break;
  602.       if (isdir(av[i]) && recur)
  603.      rmdir(av[i]);
  604.       if (!(recur && av[i][strlen(av[i])-1] == ':'))
  605.      rm_file(av[i]);
  606.    }
  607.    return (0);
  608. }
  609.  
  610. rmdir(name)
  611. char *name;
  612. {
  613.    register struct FileLock *lock, *cwd;
  614.    register FIB *fib;
  615.    register char *buf;
  616.  
  617.    buf = (char *)AllocMem(256L, MEMF_PUBLIC);
  618.    fib = (FIB *)AllocMem((long)sizeof(FIB), MEMF_PUBLIC);
  619.  
  620.    if (lock = (struct FileLock *)Lock(name, ACCESS_READ)) {
  621.       cwd = (struct FileLock *) CurrentDir(lock);
  622.       if (Examine(lock, fib)) {
  623.      buf[0] = 0;
  624.      while (ExNext(lock, fib)) {
  625.         if (CHECKBREAK()) break;
  626.         if (isdir(fib->fib_FileName))
  627.            rmdir(fib->fib_FileName);
  628.         if (buf[0]) {
  629.            rm_file(buf);
  630.         }
  631.         strcpy(buf, fib->fib_FileName);
  632.      }
  633.      if (buf[0] && !CHECKBREAK()) {
  634.         rm_file(buf);
  635.      }
  636.       }
  637.       UnLock(CurrentDir(cwd));
  638.    } else {
  639.       pError(name);
  640.    }
  641.    FreeMem(fib, (long)sizeof(FIB));
  642.    FreeMem(buf, 256L);
  643. }
  644.  
  645.  
  646.  
  647. do_history()
  648. {
  649.    register struct HIST *hist;
  650.    register int i = H_tail_base;
  651.    register int len = (av[1]) ? strlen(av[1]) : 0;
  652.  
  653.    for (hist = H_tail; hist; hist = hist->prev) {
  654.       if (len == 0 || strncmp(av[1], hist->line, len) == 0) {
  655.      printf ("%3d ", i);
  656.      puts (hist->line);
  657.       }
  658.       ++i;
  659.       if (CHECKBREAK())
  660.      break;
  661.    }
  662.    return (0);
  663. }
  664.  
  665. do_mem()
  666. {
  667.    long cfree, ffree;
  668.    extern long AvailMem();
  669.  
  670.    Forbid();
  671.    cfree = AvailMem (MEMF_CHIP);
  672.    ffree = AvailMem (MEMF_FAST);
  673.    Permit();
  674.  
  675.    if (ffree)        {
  676.    printf ("FAST memory: %ld\n", ffree);
  677.    printf ("CHIP memory: %ld\n", cfree);
  678.    }
  679.    printf ("Total  Free: %ld\n", cfree + ffree);
  680.    return(0);
  681. }
  682.  
  683. /*
  684.  * foreach var_name  ( str str str str... str ) commands
  685.  * spacing is important (unfortunetly)
  686.  *
  687.  * ac=0       1 2 3 4 5 6 7
  688.  * foreach i ( a b c ) echo $i
  689.  * foreach i ( *.c )   "echo -n "file ->";echo $i"
  690.  */
  691.  
  692. do_foreach()
  693. {
  694.    register int i, cstart, cend, old;
  695.    register char *cstr, *vname, *ptr, *scr, *args;
  696.  
  697.    cstart = i = (*av[2] == '(') ? 3 : 2;
  698.    while (i < ac) {
  699.       if (*av[i] == ')')
  700.      break;
  701.       ++i;
  702.    }
  703.    if (i == ac) {
  704.       fprintf (stderr,"')' expected\n");
  705.       return (-1);
  706.    }
  707.    ++H_stack;
  708.    cend = i;
  709.    vname = strcpy(malloc(strlen(av[1])+1), av[1]);
  710.    cstr = compile_av (av, cend + 1, ac);
  711.    ptr = args = compile_av (av, cstart, cend);
  712.    while (*ptr) {
  713.       while (*ptr == ' ' || *ptr == 9)
  714.      ++ptr;
  715.       scr = ptr;
  716.       if (*scr == '\0')
  717.      break;
  718.       while (*ptr && *ptr != ' ' && *ptr != 9)
  719.      ++ptr;
  720.       old = *ptr;
  721.       *ptr = '\0';
  722.       set_var (LEVEL_SET, vname, scr);
  723.       if (CHECKBREAK())
  724.      break;
  725.       exec_command (cstr);
  726.       *ptr = old;
  727.    }
  728.    --H_stack;
  729.    free (args);
  730.    free (cstr);
  731.    unset_var (LEVEL_SET, vname);
  732.    free (vname);
  733.    return (0);
  734. }
  735.  
  736.  
  737. do_forever(str)
  738. char *str;
  739. {
  740.    int rcode = 0;
  741.    char *ptr = next_word(str);
  742.  
  743.    ++H_stack;
  744.    for (;;) {
  745.       if (CHECKBREAK()) {
  746.      rcode = 20;
  747.      break;
  748.       }
  749.       if (exec_command (ptr) < 0) {
  750.      str = get_var(LEVEL_SET, V_LASTERR);
  751.      rcode = (str) ? atoi(str) : 20;
  752.      break;
  753.       }
  754.    }
  755.    --H_stack;
  756.    return (rcode);
  757. }
  758.  
  759.